package com.xiaomengkuan.comment.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaomengkuan.comment.entity.pojo.Comment;
import com.xiaomengkuan.comment.entity.ro.CommentPageRo;
import com.xiaomengkuan.comment.entity.vo.CommentResponseVo;
import com.xiaomengkuan.comment.mapper.CommentMapper;
import com.xiaomengkuan.comment.remote.ProductRemoteService;
import com.xiaomengkuan.comment.remote.UserRemoteService;
import com.xiaomengkuan.comment.service.CommentService;
import com.xiaomengkuan.common.entity.vo.PageVo;
import com.xiaomengkuan.common.exception.CasualException;
import com.xiaomengkuan.common.exception.RequestBodyArgumentException;
import com.xiaomengkuan.common.util.R;
import com.xiaomengkuan.common.util.YsjUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.xiaomengkuan.common.util.YsjUtil.*;

/**
 * @author Faraj Mujey
 * -- Creation Time: 2021-01-27 1:37 下午, File Encoding: utf8 --
 */
@Service
public class CommentServiceImpl implements CommentService {

    @Resource
    private CommentMapper commentMapper;
    @Resource
    private ProductRemoteService productRemoteService;
    @Resource
    private UserRemoteService userRemoteService;

    /**
     * 获取商品的所有评论
     *
     * @param id 商品id
     * @return R
     */
    @Override
    public List<CommentResponseVo> getProductComments(String id) {
        R exist = productRemoteService.isExist(id);
        if (exist.getCode() == 200) {
            List<Comment> comments =
                    commentMapper.selectList(new QueryWrapper<Comment>().eq(
                            "product_id", id).and(w -> {
                        w.eq("base_id", "0");
                    }).orderByDesc("created_time"));
            return comments.stream().map(e -> {
                CommentResponseVo commentResponseVo = new CommentResponseVo();
                BeanUtils.copyProperties(e, commentResponseVo);
                commentResponseVo.setCreatedTime(YsjUtil.getTimeStr(e.getCreatedTime()));
                Map<String, String> allEq = new HashMap<>();
                allEq.put("product_id", id);
                allEq.put("base_id", e.getId());
                List<Comment> replayComments =
                        commentMapper.selectList(new QueryWrapper<Comment>().allEq(allEq));
                List<CommentResponseVo> replayCommentResponseVos = replayComments.stream().map(re -> {
                    CommentResponseVo replayCommentResponseVo =
                            new CommentResponseVo();
                    BeanUtils.copyProperties(re, replayCommentResponseVo);
                    replayCommentResponseVo.setCreatedTime(YsjUtil.getTimeStr(re.getCreatedTime()));
                    return replayCommentResponseVo;
                }).collect(Collectors.toList());
                commentResponseVo.setReplayComments(replayCommentResponseVos);
                return commentResponseVo;
            }).collect(Collectors.toList());
        } else {
            throw new CasualException(5000, "用户不存在");
        }
    }

    /**
     * 发布评论
     *
     * @param requestBody 请求体
     * @return R
     */
    @Override
    public boolean commit(Map<String, Object> requestBody) {
        String userId = (String) requestBody.get("userId");
        String productId = (String) requestBody.get("productId");
        String context = (String) requestBody.get("context");
        String avatar = (String) requestBody.get("avatar");
        String nickname = (String) requestBody.get("nickname");
        if (stringsCompliant(userId, productId, context, avatar, nickname)) {
            R productExist = productRemoteService.isExist(productId);
            R userExist = userRemoteService.isExist(userId);
            if (productExist.getCode() == 200 && userExist.getCode() == 200) {
                Comment comment = new Comment();
                comment.setContext(context);
                comment.setBaseId("0");
                LocalDateTime now = LocalDateTime.now();
                comment.setCreatedTime(now);
                comment.setUserId(userId);
                comment.setProductId(productId);
                comment.setAvatar(avatar);
                comment.setNickname(nickname);
                int insert = commentMapper.insert(comment);
                if (insert > 0) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public boolean replay(Map<String, String> requestBody) {
        String userId = requestBody.get("userId");
        String productId = requestBody.get("productId");
        String baseId = requestBody.get("baseId");
        String context = requestBody.get("context");
        String avatar = requestBody.get("avatar");
        String nickname = requestBody.get("nickname");
        boolean b = stringsCompliant(userId, productId, baseId, context,
                avatar, nickname);
        if (b) {
            Comment comment = new Comment();
            comment.setBaseId(baseId);
            comment.setUserId(userId);
            comment.setProductId(productId);
            comment.setNickname(nickname);
            comment.setContext(context);
            comment.setCreatedTime(LocalDateTime.now());
            comment.setAvatar(avatar);
            int insert = commentMapper.insert(comment);
            if (insert > 0) {
                return true;
            }
        }
        return false;
    }

    @Override
    public PageVo<CommentResponseVo> page(CommentPageRo commentPageRo) {
        int current = commentPageRo.getCurrent();
        int size = commentPageRo.getSize();
        String productId = commentPageRo.getProductId();
        // 评论查询条件
        IPage<Comment> commentPage = new Page<>(current, size);
        Map<String, String> allEqConditions_Base = new HashMap<>();
        allEqConditions_Base.put("product_id", productId);
        allEqConditions_Base.put("base_id", "0");
        Integer baseCommentCount = commentMapper.selectCount(new QueryWrapper<Comment>().allEq(allEqConditions_Base));
        // 查询顶级评论 按照时间降序
        IPage<Comment> commentIPage = commentMapper.selectPage(commentPage,
                new QueryWrapper<Comment>().allEq(allEqConditions_Base).orderByDesc("created_time"));
        long[] total = new long[]{commentIPage.getTotal()};
        List<CommentResponseVo> collect = commentIPage.getRecords().stream().map(e -> {
            CommentResponseVo commentResponseVo = new CommentResponseVo();
            BeanUtils.copyProperties(e, commentResponseVo);
            // 设置时间字符串
            commentResponseVo.setCreatedTime(getTimeStr(e.getCreatedTime()));
            // 回复评论查询条件
            Map<String, String> allEqConditions_Child = new HashMap<>();
            allEqConditions_Child.put("product_id", productId);
            allEqConditions_Child.put("base_id", e.getId());
            IPage<Comment> commentPage_Child = new Page<>(1, 2);
            IPage<Comment> commentsPage_Child =
                    commentMapper.selectPage(commentPage_Child,
                            new QueryWrapper<Comment>().allEq(allEqConditions_Child).orderByDesc("created_time"));
            // total ++
            total[0] += commentsPage_Child.getTotal();
            // 填充回复评论响应对象
            List<CommentResponseVo> collect_Child =
                    commentsPage_Child.getRecords().stream().map(en -> {
                        CommentResponseVo commentResponse_Child =
                                new CommentResponseVo();
                        BeanUtils.copyProperties(en, commentResponse_Child);
                        commentResponse_Child.setCreatedTime(getTimeStr(en.getCreatedTime()));
                        return commentResponse_Child;
                    }).collect(Collectors.toList());
            commentResponseVo.setReplayComments(collect_Child);
            return commentResponseVo;
        }).collect(Collectors.toList());
        return pageFilling(current, size, baseCommentCount, collect);
    }

    @Override
    public PageVo<CommentResponseVo> getReplayCommentsPage(Map<String, Object> requestBody) {
        Integer current = (Integer) requestBody.get("current");
        Integer size = (Integer) requestBody.get("size");
        String productId = (String) requestBody.get("productId");
        String baseId = (String) requestBody.get("baseId");
        // 判断是否为空
        boolean b = objsCompliant(current, size, productId, productId, baseId);
        if (b) {
            // 构造查询条件
            Map<String, String> allEqConditions = new HashMap<>();
            allEqConditions.put("product_id", productId);
            allEqConditions.put("base_id", baseId);
            QueryWrapper<Comment> wrapper = new QueryWrapper<>();
            wrapper.allEq(allEqConditions);
            wrapper.orderByDesc("created_time");
            // 分页对象
            Page<Comment> commentPage = new Page<>(current, size);
            Page<Comment> page = commentMapper.selectPage(commentPage, wrapper);
            // commentResponseVoList
            List<CommentResponseVo> collect = page.getRecords().stream().map(e -> {
                CommentResponseVo commentResponseVo = new CommentResponseVo();
                BeanUtils.copyProperties(e, commentResponseVo);
                commentResponseVo.setCreatedTime(getTimeStr(e.getCreatedTime()));
                return commentResponseVo;
            }).collect(Collectors.toList());
            return pageFilling(current, size, page.getTotal(), collect);
        } else {
            throw new RequestBodyArgumentException(5000, "缺少请求参数");
        }
    }

    @Override
    public Integer commentCount(String userId) {
        return commentMapper.selectCount(new QueryWrapper<Comment>().eq("user_id",
                userId));
    }
}
